hhkb
컴퓨터과학

어셈블리_03_명령어 집합과 제어 흐름

작성자 : Heehyeon Yoo|2025-10-09
# Assembly# Instruction# Control Flow# JCC

어셈블리어에는 if, while 같은 구조화된 제어문이 존재하지 않는다. 대신 비교(Compare)점프(Jump) 명령어의 조합을 통해 프로그램의 흐름을 제어한다.

1. 기본 명령어

가장 빈번하게 사용되는 데이터 이동 및 연산 명령어다.

  • MOV A, B: B의 값을 A로 복사한다.
  • ADD / SUB: 덧셈 및 뺄셈을 수행한다.
  • INC / DEC: 값을 1 증가시키거나 감소시킨다.
  • LEA(Load Effective Address): 메모리 참조가 아닌, 주소값 자체의 연산을 수행한다. 포인터 연산이나 간단한 산술 연산에 최적화되어 있다.(MOV는 주소 안의 값을 가져오지만, LEA는 주소 그 자체를 가져온다)

2. 분기문의 원리: CMP와 JMP

조건문은 CMP 명령어로 플래그(Flag)를 설정하고, Jcc 명령어로 플래그 상태를 확인하여 분기하는 2단계 과정을 거친다.

(1) 비교: CMP(Compare)

cmp rax, rbx

두 값의 차이(rax - rbx)를 계산한다. 결과값은 저장하지 않고, 대신 RFLAGS 레지스터의 상태 비트(ZF, SF 등)를 갱신한다.

  • ZF (Zero Flag): 결과가 0이면(두 값이 같으면) 1로 설정된다.
  • SF (Sign Flag): 결과가 음수면 1로 설정된다.

Note: TEST 명령어와의 차이
리버싱을 하다 보면 CMP 대신 TEST 명령어가 자주 보인다. (예: test rax, rax)
CMP는 뺄셈 연산(-)을 통해 차이를 확인하지만, TEST는 논리곱(AND) 연산을 수행한다. 주로 "값이 0인지 아닌지" 또는 "NULL 포인터 체크"를 할 때 CMP보다 효율적이라서 자주 사용된다.

(2) 분기: Jcc(Jump Condition)

플래그 상태에 따라 실행 흐름을 변경한다.

명령어의미조건
JEJump if Equal값이 같을 때 (ZF=1)
JNEJump if Not Equal값이 다를 때 (ZF=0)
JGJump if Greater클 때
JLJump if Less작을 때

3. If-Else 구현 패턴

고급 언어의 구조가 어셈블리어로 변환되면 다음과 같은 형태가 된다.

    cmp rax, 10
    je  is_ok       ; 조건 만족 시 점프

    ; [Else 블록]
    call fail
    jmp  finish     ; 필수: 여기서 점프하지 않으면 아래 코드로 흘러내림(Fall-through)

is_ok:
    ; [If 블록]
    call ok

finish:
    ; 종료

Else 블록 끝에 무조건 분기(JMP)를 넣지 않으면, 의도치 않게 Is_ok 블록까지 실행되는 Fall-through 오류가 발생하므로 주의가 필요하다.